<template>
  <div id="model_edit">
    <h1 v-if="isUpdate">编辑 Model</h1>
    <h1 v-else>创建 Model</h1>
    <el-row :gutter="20">
      <el-col :span="6">
        <el-form ref="modelForm" :model="bean"
            :rules="rules" @validate="formValidated">
          <el-form-item label="名称" prop="name">
            <el-input v-model="bean.name" minlength="1" maxlength="40"/>
          </el-form-item>
          <el-form-item label="Schema" prop="dbSchema">
            <el-input v-model="bean.dbSchema" maxlength="40"/>
          </el-form-item>
          <el-form-item label="表名" prop="dbTable">
            <el-input v-model="bean.dbTable" minlength="1" maxlength="40"/>
          </el-form-item>
        </el-form>
      </el-col>
      <el-col :span="18">
        <div id="fields_header">
          <h3>字段列表</h3>
          <el-button type="primary" @click="addField()">添加字段</el-button>
        </div>
        <el-table stripe :data="bean.fields">
          <el-table-column prop="name" label="名称"/>
          <el-table-column prop="dataTypeDesc" label="数据类型" :width="120"/>
          <el-table-column prop="dbColumn" label="列名"/>
          <el-table-column prop="precisionOrLength" label="精度或长度" :width="120"/>
          <el-table-column fixed="right" label="操作" :width="150">
            <template slot-scope="scope">
              <el-button type="primary" plain size="small" @click="handleEdit(scope.row, scope.$index)">编辑</el-button>
              <el-button type="danger" plain size="small" @click="handleRemove(scope.$index)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-col>
    </el-row>
    <FieldEdit :index="editingIndex" :beanName="bean.name" :field="editingField" @submit="handleField"/>
    <div>
      <el-button type="primary" :disabled="invalid" :loading="submitting" @click="submit()">提交</el-button>
      <el-button @click="cancel()">取消</el-button>
    </div>
    <error-alert :errorMessage="errorMessage" @ok="errorOk"/>
  </div>
</template>

<script>
import Vue from "vue";

import elementLayout from "../plugins/element/layout.js";
import elementForm from "../plugins/element/form.js";
import elementTable from "../plugins/element/table.js";
import elementInput from "../plugins/element/input.js";
import elementButton from "../plugins/element/button.js";

import http from "../util/http.js";

import FieldEdit from "./FieldEdit.vue";
import ErrorAlert from "../components/ErrorAlert.vue";
import { validateNotBlank, validateSQLIdentifier } from "../plugins/element/validators.js";

function descDataType(dataType) {
  switch (dataType) {
    case "VARCHAR":
      return "字符串";
    case "INT32":
      return "32位整数";
    case "INT64":
      return "64位整数";
    case "DECIMAL":
      return "小数";
    case "UUID":
      return "UUID";
    case "DATETIME":
      return "日期时间";
    case "DATE":
      return "日期";
    case "TIME":
      return "时间";
    case "CLOB":
      return "长文本";
    case "BLOB":
      return "二进制";
  }
  return "未定义";
}

const component = {
  name: "model_edit",
  data() {
    return {
      bean: {
        id: "",
        name: "",
        dbSchema: "",
        dbTable: "",
        fields: []
      },

      editingIndex: -1,
      editingField: null,
      submitting: false,
      errorMessage: "",

      isFieldValid: {
        name: false,
        dbSchema: true,
        dbTable: false
      },
      rules: {
        name: [
          { validator: validateNotBlank, message: "请输入 Model 名称", trigger: "change" },
          { max: 40, message: "Model 名称最多 40 个字符", trigger: "change" },
          {
            validator: function (rule, value, callback) {
              if (("" + value).trim() === ("" + Number(value))) {
                callback(new Error("Model 名称不能是一个数字"));
              } else {
                callback();
              }
            },
            trigger: "change"
          }
        ],
        dbSchema: [
          { max: 40, message: "Schema 名最多 40 个字符", trigger: "change" },
          { validator: validateSQLIdentifier, trigger: "change" }
        ],
        dbTable: [
          { validator: validateNotBlank, message: "请输入数据库表的表名", trigger: "change" },
          { max: 40, message: "表名最多 40 个字符", trigger: "change" },
          { validator: validateSQLIdentifier, trigger: "change" }
        ]
      }
    };
  },
  computed: {
    isUpdate() {
      return !!this.bean.id;
    },
    invalid() {
      return !this.isFieldValid.name || !this.isFieldValid.dbSchema || !this.isFieldValid.dbTable;
    }
  },
  created() {
    this.bean.id = this.$route.params.id || "";
    this.bean.name = this.$route.params.name || "";
    this.bean.dbSchema = this.$route.params.dbSchema || null;
    this.bean.dbTable = this.$route.params.dbTable || "";
    this.refresh();
  },
  methods: {
    refresh() {
      if (!this.isUpdate) {
        return;
      }
      this.$store.commit("setLoading");
      http.get( http.receiveJSON({
        url: "/managed-bean/0/" + this.bean.id
      }) ).then(response => {
        this.bean = response.data.content;
        this.bean.fields.forEach(function (item) {
          item.dataTypeDesc = descDataType(item.dataType);
        });

        this.isFieldValid.name = true;
        this.isFieldValid.dbTable = true;

        this.$store.commit("unsetLoading");
      }).catch((ex) => {
        console.error(ex);
        this.$store.commit("unsetLoading");
      });
    },

    formValidated(prop, valid) {
      this.isFieldValid[prop] = valid;
    },
    submit() {
      this.$refs.modelForm.validate(isValid => {
        if (!isValid) {
          return;
        }
        this.submitting = true;
        http.post( http.receiveJSON(http.sendJSON({
          url: "/managed-bean/0",
          data: this.bean
        })) ).then(response => {
          if ((response.data && response.data.code) !== "ok") {
            throw new Error('The response code is not "ok"');
          }
          this.submitting = true;
          this.$router.back();
        }).catch((ex) => {
          console.error(ex);
          this.errorMessage = (this.isUpdate ? "更新" : "创建") + " Model 出错";
        });
      });
    },
    cancel() {
      this.$router.back();
    },
    errorOk() {
      this.errorMessage = "";
    },

    addField() {
      this.editingField = {
        id: "",
        name: "",
        dataType: "VARCHAR",
        dbColumn: "",
        precisionOrLength: null,
        dateTimePattern: null
      };
      this.editingIndex = this.bean.fields.length;
    },
    handleEdit(row, index) {
      this.editingField = row;
      this.editingIndex = index;
    },
    handleRemove(index) {
      this.bean.fields.splice(index, 1);
    },
    handleField(field) {
      if (!field) {
        this.editingIndex = -1;
        return;
      }
      field.dataTypeDesc = descDataType(field.dataType);
      if (this.editingIndex >= this.bean.fields.length) {
        field.id = "";
        this.bean.fields.push(field);
      } else {
        this.bean.fields.splice(this.editingIndex, 1, field);
      }
      this.editingIndex = -1;
    }
  },
  components: {
    FieldEdit,
    ErrorAlert
  }
};

elementLayout(component);
elementForm(component);
elementTable(component);
elementInput(component);
elementButton(component);

export default component;
</script>

<style scoped>
#fields_header {
  display: flex;
  justify-content: space-between;
}
#fields_header h3, #fields_header button.el-button {
  align-self: center;
}
#fields_header h3 {
  font-family: STSong, NSimSun, SimSun, Times, "Times New Roman", Georgia, serif;
  font-size: 1.1em;
}
</style>
